package com.gcloud.mesh.security;

import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;

import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.boot.env.OriginTrackedMapPropertySource;
import org.springframework.context.ApplicationListener;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import org.springframework.stereotype.Component;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;

import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
public class PasswordPropertyListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {
	
	private static final String AUTH = "password";
	private static final String MIMA = "mima";
	private static Map<String, String> mimaMap = new HashMap<String, String>();
    static {
    	mimaMap.put("spring.datasource.dynamic.datasource.master.mima", null);
    	mimaMap.put("spring.mail.mima", null);
    	mimaMap.put("spring.redis.mima", null);
    	mimaMap.put("spring.rabbitmq.mima", null);
    	mimaMap.put("swagger.basic.mima", null);
    	mimaMap.put("mesh.data-security.mima", null);
    	mimaMap.put("mesh.data-classification.mima", null);
    }

	@Override
	public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
		// TODO Auto-generated method stub
		ConfigurableEnvironment environment = event.getEnvironment();
        MutablePropertySources  sources     = environment.getPropertySources();
        sources.forEach(source -> {
            PropertySource propertySource = sources.get(source.getName());
            if (propertySource instanceof OriginTrackedMapPropertySource) {
                //保存处理过后的值
                Map<String, Object> convertPropertySource = new HashMap<>();
                //重新定义一个PropertySource，覆盖原来的
                OriginTrackedMapPropertySource newMapPropertySource = new OriginTrackedMapPropertySource(propertySource.getName(),
                                                                               convertPropertySource);
                String[] propertyNames = ((MapPropertySource) propertySource).getPropertyNames();
                Stream.of(propertyNames).forEach(name -> {
                	
                    Object value = propertySource.getProperty(name);
                    if (value instanceof String) {                       
                        if(mimaMap.containsKey(name)) {
                        	String originalValue = (String) value;
                        	String authTypeName = getTypeName(name);
                        	String authName = convertName(authTypeName);
                        	convertPropertySource.put(authName, value);
                        	log.info("{} 转换成 {}={}", name, authName, value);
                        }else {
                            convertPropertySource.put(name, value);
                        }
                    } else {
                        convertPropertySource.put(name, value);
                    }
                });
                //处理过后值替换原来的PropertySource
                sources.replace(source.getName(), newMapPropertySource);
            }
        });
	}
	
	private String getTypeName(String name) {
		String suffix = MIMA;
		if(!StringUtils.isNotBlank(name)) {
			return null;
		}
		int index = name.indexOf(MIMA);
		return name.substring(0, index-1);
	}
	
	private String convertName(String name) {
		String suffix = AUTH;
		if(!StringUtils.isNotBlank(name)) {
			return null;
		}
		String newName = name + "." + suffix;
		return newName;
	}

}
